﻿//*********************************************************
//
// Copyright (c) Microsoft. All rights reserved.
// This code is licensed under the MIT License (MIT).
// THIS CODE IS PROVIDED *AS IS* WITHOUT WARRANTY OF
// ANY KIND, EITHER EXPRESS OR IMPLIED, INCLUDING ANY
// IMPLIED WARRANTIES OF FITNESS FOR A PARTICULAR
// PURPOSE, MERCHANTABILITY, OR NON-INFRINGEMENT.
//
//*********************************************************

using System;
using System.Collections.Generic;
using System.Diagnostics;
using System.IO;
using System.Linq;
using System.Text;
using Windows.ApplicationModel.Resources;
using Windows.ApplicationModel.Resources.Core;
using Windows.Media.SpeechSynthesis;
using Windows.Storage;
using Windows.Storage.Pickers;
using Windows.UI.Xaml;
using Windows.UI.Xaml.Controls;
using Windows.UI.Xaml.Media;
using Windows.UI.Xaml.Navigation;

namespace SDKTemplate
{
    /// <summary>
    /// An empty page that can be used on its own or navigated to within a Frame.
    /// </summary>
    public sealed partial class Scenario1 : Page
    {
        MainPage rootPage = MainPage.Current;
        string textfullstr = string.Empty;
        private SpeechSynthesizer synthesizer;
        private ResourceContext speechContext;
        ResourceLoader loader = new Windows.ApplicationModel.Resources.ResourceLoader();
        public Scenario1()
        {
            this.InitializeComponent();
            PickAFileButton.Click += new RoutedEventHandler(PickAFileButton_Click);
            repageButton.Click += RepageButton_Click;
            synthesizer = new SpeechSynthesizer();

            speechContext = ResourceContext.GetForCurrentView();
            speechContext.Languages = new string[] { SpeechSynthesizer.DefaultVoice.Language };

          //  speechResourceMap = ResourceManager.Current.MainResourceMap.GetSubtree("LocalizationTTSResources");

            InitializeListboxVoiceChooser();
        }

        private async void  RepageButton_Click(object sender, RoutedEventArgs e)
        {
            if (int.Parse(perpagecount.Text)>2000)
            {
                 var counttip = loader.GetString("counttip");
                var messageDialog = new Windows.UI.Popups.MessageDialog(counttip);
                await messageDialog.ShowAsync();
            }
            else
            {
                pagelist.ItemsSource = makestringlistfromfromstr(textfullstr, int.Parse(perpagecount.Text));
                App.Fulltextlist = makestringlistfromfromstr(textfullstr, int.Parse(perpagecount.Text));
            }
        }

        private async void PickAFileButton_Click(object sender, RoutedEventArgs e)
        {
            // Clear previous returned file name, if it exists, between iterations of this scenario
            OutputTextBlock.Text = "";

            FileOpenPicker openPicker = new FileOpenPicker();
            openPicker.ViewMode = PickerViewMode.Thumbnail;
            openPicker.SuggestedStartLocation = PickerLocationId.PicturesLibrary;
            openPicker.FileTypeFilter.Add(".txt");
            openPicker.FileTypeFilter.Add(".rtf");
            //openPicker.FileTypeFilter.Add(".png");
            StorageFile file = await openPicker.PickSingleFileAsync();
            if (file != null)
            {
                // Application now has read/write access to the picked file
                OutputTextBlock.Text = file.Name;
                Output.Visibility = Visibility.Visible;
                // 将指定的文本内容写入到指定的文件
                using (Stream stream = await file.OpenStreamForReadAsync())
                {
                    byte[] bytes = StreamToBytes(stream);
                    Debug.WriteLine(bytes.Length + "bytes.length");
                    StreamReader reader = new StreamReader(stream,true);
                  
                      textfullstr = reader.ReadToEnd();
                    totaltb.Text = textfullstr.Length.ToString();
                    Debug.WriteLine(textfullstr.Length + "textfullstr.length");
                    textToSynthesize.Text = textfullstr;
                    pagelist.ItemsSource = makestringlistfromfromstr(textfullstr, int.Parse(perpagecount.Text));
                    App.Fulltextlist = makestringlistfromfromstr(textfullstr, int.Parse(perpagecount.Text));
                }
                

            }
            else
            {
                OutputTextBlock.Text = "";
            }
        }
     
        public byte[] StreamToBytes(Stream stream)
        {
            byte[] bytes = new byte[stream.Length];
            stream.Read(bytes, 0, bytes.Length);
            // 设置当前流的位置为流的开始
            stream.Seek(0, SeekOrigin.Begin);
            return bytes;
        }
        private  Encoding AutoEncoding(byte[] bom)
        {
            if (bom.Length != 4)
            {
                throw new ArgumentException("EncodingScrutator.AutoEncoding 参数大小不等于4");
            }

            // Analyze the BOM

            if (bom[0] == 0x2b && bom[1] == 0x2f && bom[2] == 0x76)
                return Encoding.UTF7; //85 116 102 55    //utf7 aa 97 97 0 0
            //utf7 编码 = 43 102 120 90

            if (bom[0] == 0xef && bom[1] == 0xbb && bom[2] == 0xbf)
                return Encoding.UTF8; //无签名 117 116 102 56
            // 130 151 160 231
            if (bom[0] == 0xff && bom[1] == 0xfe)
                return Encoding.Unicode; //UTF-16LE

            if (bom[0] == 0xfe && bom[1] == 0xff)
                return Encoding.BigEndianUnicode; //UTF-16BE

            if (bom[0] == 0 && bom[1] == 0 && bom[2] == 0xfe && bom[3] == 0xff) return Encoding.UTF32;

            return Encoding.ASCII; //如果返回ASCII可能是GBK、无签名 utf8
        }
        private async void Speaktext(string str)
        {
            // If the media is playing, the user has pressed the button to stop the playback.
            if (media.CurrentState.Equals(MediaElementState.Playing))
            {
                media.Stop();
               
                var btnstartstr = loader.GetString("start");
                btnSpeak.Content = btnstartstr;
            }
            else
            {
                string text = str;

                if (!String.IsNullOrEmpty(text))
                {
                    // Change the button label. You could also just disable the button if you don't want any user control.
                   
                    var btnstartstr = loader.GetString("stop");
                    btnSpeak.Content = btnstartstr;

                    try
                    {
                        // Create a stream from the text. This will be played using a media element.
                        if (text.Length > 1000)
                        {
                            SpeechSynthesisStream synthesisStream = await synthesizer.SynthesizeTextToStreamAsync(text.Substring(0, 1000));
                            media.AutoPlay = true;
                            media.SetSource(synthesisStream, synthesisStream.ContentType);
                            media.Play();
                        }

                        else
                        {
                            SpeechSynthesisStream synthesisStream = await synthesizer.SynthesizeTextToStreamAsync(text);
                            media.AutoPlay = true;
                            media.SetSource(synthesisStream, synthesisStream.ContentType);
                            media.Play();
                        }


                        // Set the source and start playing the synthesized audio stream.

                    }
                    catch (Exception)
                    {
                        // If the text is unable to be synthesized, throw an error message to the user.
                     
                       
                        var messageDialog = new Windows.UI.Popups.MessageDialog("Unable to synthesize text");
                        await messageDialog.ShowAsync();
                    }
                }
            }
        }

        private async void Speak_Click(object sender, RoutedEventArgs e)
        {
            // If the media is playing, the user has pressed the button to stop the playback.
            if (media.CurrentState.Equals(MediaElementState.Playing))
            {
                media.Stop();
                var btnstartstr = loader.GetString("start");
                btnSpeak.Content = btnstartstr;
            }
            else
            {
                string text = textToSynthesize.Text;

                if (!String.IsNullOrEmpty(text))
                {
                    // Change the button label. You could also just disable the button if you don't want any user control.
                    var btnstartstr = loader.GetString("stop");
                    btnSpeak.Content = btnstartstr;

                    try
                    {
                        // Create a stream from the text. This will be played using a media element.
                        if (text.Length > 1000)
                        {
                            SpeechSynthesisStream synthesisStream = await synthesizer.SynthesizeTextToStreamAsync(text.Substring(0, 1000));
                            media.AutoPlay = true;
                            media.SetSource(synthesisStream, synthesisStream.ContentType);
                            media.Play();
                        }

                        else
                        {
                            SpeechSynthesisStream synthesisStream = await synthesizer.SynthesizeTextToStreamAsync(text);
                            media.AutoPlay = true;
                            media.SetSource(synthesisStream, synthesisStream.ContentType);
                            media.Play();
                        }


                        // Set the source and start playing the synthesized audio stream.
                     
                    }
                    catch (Exception)
                    {
                        // If the text is unable to be synthesized, throw an error message to the user.
                    //    btnSpeak.Content = "Speak";
                        var messageDialog = new Windows.UI.Popups.MessageDialog("Unable to synthesize text");
                        await messageDialog.ShowAsync();
                    }
                }
            }
        }
        private void TB_Tapped(object sender, RoutedEventArgs e)
        {
            //find out which game object was clicked
            FrameworkElement source_image = e.OriginalSource as FrameworkElement;
            TextBlock TTB = sender as TextBlock;
            App.textselectindex = pagelist.SelectedIndex;
            Speaktext(TTB.Text);

        }
            /// <summary>
            /// This is invoked when the stream is finished playing.
            /// </summary>
            /// <remarks>
            /// In this case, we're changing the button label based on the state.
            /// </remarks>
            /// <param name="sender">unused object parameter</param>
            /// <param name="e">unused event parameter</param>
            void media_MediaEnded(object sender, RoutedEventArgs e)
        {
            if (App.textselectindex < App.Fulltextlist.Count)
            {
                string nextstr = App.Fulltextlist.ElementAt  (App.textselectindex);
                Speaktext(nextstr);
                App.textselectindex = App.textselectindex + 1;
            }
            else
            {
                var btnstartstr = loader.GetString("start");
                btnSpeak.Content = btnstartstr;
            }
        }

        /// <summary>
        /// This creates items out of the system installed voices. The voices are then displayed in a listbox.
        /// This allows the user to change the voice of the synthesizer in your app based on their preference.
        /// </summary>
        private void InitializeListboxVoiceChooser()
        {
            // Get all of the installed voices.
            var voices = SpeechSynthesizer.AllVoices;

            // Get the currently selected voice.
            VoiceInformation currentVoice = synthesizer.Voice;

            foreach (VoiceInformation voice in voices.OrderBy(p => p.Language))
            {
                ComboBoxItem item = new ComboBoxItem();
                item.Name = voice.DisplayName;
                item.Tag = voice;
                item.Content = voice.DisplayName + " (Language: " + voice.Language + ")";
                listboxVoiceChooser.Items.Add(item);

                // Check to see if we're looking at the current voice and set it as selected in the listbox.
                if (currentVoice.Id == voice.Id)
                {
                    item.IsSelected = true;
                    listboxVoiceChooser.SelectedItem = item;
                }
            }
        }

        /// <summary>
        /// This is called when the user has selects a voice from the drop down.
        /// </summary>
        /// <param name="sender">unused object parameter</param>
        /// <param name="e">unused event parameter</param>
        private void ListboxVoiceChooser_SelectionChanged(object sender, SelectionChangedEventArgs e)
        {
            ComboBoxItem item = (ComboBoxItem)(listboxVoiceChooser.SelectedItem);
            VoiceInformation voice = (VoiceInformation)(item.Tag);
            synthesizer.Voice = voice;

            // update UI text to be an appropriate default translation.
           // speechContext.Languages = new string[] { voice.Language };
           // textToSynthesize.Text = speechResourceMap.GetValue("SynthesizeTextDefaultText", speechContext).ValueAsString;
        }
        public List<string> makestringlistfromfromstr(string inputstr,int perpagewrodnumber) {

            List<string> resut = new List<string>();
            int totallength = inputstr.Length;
            if (totallength <= perpagewrodnumber)
            {
                resut.Add(inputstr);
            }
            else {
                int totalpagenumber = totallength / perpagewrodnumber;
                for (int i = 0; i < totalpagenumber ; i++)
                {
                    if (perpagewrodnumber * (i + 1) < totallength)
                    {
                     string tempstr=   inputstr.Substring(perpagewrodnumber * i, perpagewrodnumber);
                        resut.Add(tempstr);
                                                
                    }

                }
                
                    string lasttempstr = inputstr.Substring(perpagewrodnumber * totalpagenumber, totallength - perpagewrodnumber*resut.Count()- 1);
                    resut.Add(lasttempstr);

               
            }

            return resut;
                

        }

    }
}
